{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import os,random,shutil\n",
    "np.random.seed(7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 为Keras模型准备数据集\n",
    "#1，指定一些超参数：\n",
    "FOLDER='E:\\PyProjects\\DataSet\\Small_set_5_Class'\n",
    "train_data_dir=os.path.join(FOLDER,'train')\n",
    "val_data_dir=os.path.join(FOLDER,'test')\n",
    "train_samples_num=400 # train set中全部照片数\n",
    "val_samples_num=100\n",
    "IMG_W,IMG_H,IMG_CH=150,150,3 # 单张图片的大小\n",
    "batch_size=50 # 这儿要保证400和100能除断\n",
    "epochs=50  # 用比较少的epochs数目做演示，节约训练时间\n",
    "class_num=5 # 此处有5个类别\n",
    "\n",
    "save_folder='E:\\PyProjects\\/DataSet\\/FireAI\\/DeepLearning\\/FireAI009' # bottleneck特征保存位置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 此处的训练集和测试集并不是原始图片的train set和test set，而是用VGG16对图片提取的特征，这些特征组成新的train set和test set\n",
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "from keras.models import Sequential\n",
    "from keras.layers import Dropout, Flatten, Dense\n",
    "from keras import applications\n",
    "def save_bottlebeck_features():\n",
    "    datagen = ImageDataGenerator(rescale=1. / 255) # 不需图片增强\n",
    "\n",
    "    # build the VGG16 network\n",
    "    model = applications.VGG16(include_top=False, weights='imagenet') \n",
    "    # 使用imagenet的weights作为VGG16的初始weights,由于只是特征提取，故而只取前面的卷积层而不需要DenseLayer，故而include_top=False\n",
    "\n",
    "    generator = datagen.flow_from_directory( # 产生train set\n",
    "        train_data_dir,\n",
    "        target_size=(IMG_W, IMG_H),\n",
    "        batch_size=batch_size,\n",
    "        class_mode='categorical', # 这个地方要修改，要不然出错\n",
    "        shuffle=False) # 必须为False，否则顺序打乱之后，和后面的label对应不上。\n",
    "    bottleneck_features_train = model.predict_generator(\n",
    "        generator, train_samples_num // batch_size) \n",
    "    np.save(os.path.join(save_folder,'bottleneck_features_train.npy'), bottleneck_features_train)\n",
    "    print('bottleneck features of train set is saved.')\n",
    "\n",
    "    generator = datagen.flow_from_directory(\n",
    "        val_data_dir,\n",
    "        target_size=(IMG_W, IMG_H),\n",
    "        batch_size=batch_size,\n",
    "        class_mode='categorical',\n",
    "        shuffle=False)\n",
    "    bottleneck_features_validation = model.predict_generator(\n",
    "        generator, val_samples_num // batch_size)\n",
    "    np.save(os.path.join(save_folder,'bottleneck_features_val.npy'),bottleneck_features_validation)\n",
    "    print('bottleneck features of test set is saved.')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 400 images belonging to 5 classes.\n",
      "bottleneck features of train set is saved.\n",
      "Found 100 images belonging to 5 classes.\n",
      "bottleneck features of test set is saved.\n"
     ]
    }
   ],
   "source": [
    "save_bottlebeck_features()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "def my_model():\n",
    "    '''\n",
    "    自定义一个模型，该模型仅仅相当于一个分类器，只包含有全连接层，对提取的特征进行分类即可\n",
    "    :return:\n",
    "    '''\n",
    "    # 模型的结构\n",
    "    model = Sequential()\n",
    "    model.add(Flatten(input_shape=train_data.shape[1:])) # 将所有data进行flatten\n",
    "    model.add(Dense(256, activation='relu')) # 256个全连接单元\n",
    "    model.add(Dropout(0.5)) # dropout正则\n",
    "    model.add(Dense(class_num, activation='softmax')) # 与二分类不同之处：要用Dense(class_num)和softmax\n",
    "\n",
    "    # 模型的配置\n",
    "    model.compile(optimizer='rmsprop',\n",
    "                  loss='categorical_crossentropy',\n",
    "                  metrics=['accuracy']) # model的optimizer等\n",
    "\n",
    "    return model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 400 samples, validate on 100 samples\n",
      "Epoch 1/50\n",
      "400/400 [==============================] - 1s 2ms/step - loss: 4.8496 - acc: 0.4725 - val_loss: 3.4864 - val_acc: 0.6900\n",
      "Epoch 2/50\n",
      "400/400 [==============================] - 0s 878us/step - loss: 3.4436 - acc: 0.7400 - val_loss: 3.3577 - val_acc: 0.7400\n",
      "Epoch 3/50\n",
      "400/400 [==============================] - 0s 845us/step - loss: 0.6014 - acc: 0.9300 - val_loss: 0.1798 - val_acc: 0.9600\n",
      "Epoch 4/50\n",
      "400/400 [==============================] - 0s 865us/step - loss: 0.0475 - acc: 0.9900 - val_loss: 0.1656 - val_acc: 0.9500\n",
      "Epoch 5/50\n",
      "400/400 [==============================] - 0s 850us/step - loss: 0.0384 - acc: 0.9825 - val_loss: 0.7421 - val_acc: 0.8400\n",
      "Epoch 6/50\n",
      "400/400 [==============================] - 0s 985us/step - loss: 0.0277 - acc: 0.9900 - val_loss: 0.1592 - val_acc: 0.9500\n",
      "Epoch 7/50\n",
      "400/400 [==============================] - 0s 868us/step - loss: 0.0055 - acc: 1.0000 - val_loss: 0.2057 - val_acc: 0.9500\n",
      "Epoch 8/50\n",
      "400/400 [==============================] - 0s 860us/step - loss: 0.0899 - acc: 0.9725 - val_loss: 1.7375 - val_acc: 0.8000\n",
      "Epoch 9/50\n",
      "400/400 [==============================] - 0s 858us/step - loss: 0.1618 - acc: 0.9700 - val_loss: 0.1664 - val_acc: 0.9500\n",
      "Epoch 10/50\n",
      "400/400 [==============================] - 0s 870us/step - loss: 0.0040 - acc: 1.0000 - val_loss: 0.1750 - val_acc: 0.9500\n",
      "Epoch 11/50\n",
      "400/400 [==============================] - 0s 860us/step - loss: 0.0023 - acc: 1.0000 - val_loss: 0.1830 - val_acc: 0.9500\n",
      "Epoch 12/50\n",
      "400/400 [==============================] - 0s 860us/step - loss: 0.0015 - acc: 1.0000 - val_loss: 0.1800 - val_acc: 0.9500\n",
      "Epoch 13/50\n",
      "400/400 [==============================] - 0s 868us/step - loss: 0.1326 - acc: 0.9700 - val_loss: 1.8995 - val_acc: 0.7700\n",
      "Epoch 14/50\n",
      "400/400 [==============================] - 0s 858us/step - loss: 0.1799 - acc: 0.9625 - val_loss: 0.2347 - val_acc: 0.9500\n",
      "Epoch 15/50\n",
      "400/400 [==============================] - 0s 878us/step - loss: 9.9769e-04 - acc: 1.0000 - val_loss: 0.2378 - val_acc: 0.9500\n",
      "Epoch 16/50\n",
      "400/400 [==============================] - 0s 880us/step - loss: 5.2125e-04 - acc: 1.0000 - val_loss: 0.2311 - val_acc: 0.9500\n",
      "Epoch 17/50\n",
      "400/400 [==============================] - 0s 873us/step - loss: 8.6575e-04 - acc: 1.0000 - val_loss: 0.2238 - val_acc: 0.9500\n",
      "Epoch 18/50\n",
      "400/400 [==============================] - 0s 870us/step - loss: 7.4481e-04 - acc: 1.0000 - val_loss: 0.2198 - val_acc: 0.9500\n",
      "Epoch 19/50\n",
      "400/400 [==============================] - 0s 873us/step - loss: 3.9374e-04 - acc: 1.0000 - val_loss: 0.2264 - val_acc: 0.9500\n",
      "Epoch 20/50\n",
      "400/400 [==============================] - 0s 883us/step - loss: 4.1364e-04 - acc: 1.0000 - val_loss: 0.2171 - val_acc: 0.9500\n",
      "Epoch 21/50\n",
      "400/400 [==============================] - 0s 998us/step - loss: 8.5401e-04 - acc: 1.0000 - val_loss: 0.2197 - val_acc: 0.9500\n",
      "Epoch 22/50\n",
      "400/400 [==============================] - 0s 993us/step - loss: 1.1582e-04 - acc: 1.0000 - val_loss: 0.2295 - val_acc: 0.9500\n",
      "Epoch 23/50\n",
      "400/400 [==============================] - 0s 883us/step - loss: 0.1329 - acc: 0.9600 - val_loss: 0.2188 - val_acc: 0.9700\n",
      "Epoch 24/50\n",
      "400/400 [==============================] - 0s 858us/step - loss: 0.0068 - acc: 0.9975 - val_loss: 0.2307 - val_acc: 0.9700\n",
      "Epoch 25/50\n",
      "400/400 [==============================] - 0s 868us/step - loss: 8.6239e-04 - acc: 1.0000 - val_loss: 0.2342 - val_acc: 0.9500\n",
      "Epoch 26/50\n",
      "400/400 [==============================] - 0s 865us/step - loss: 1.1607e-05 - acc: 1.0000 - val_loss: 0.2344 - val_acc: 0.9500\n",
      "Epoch 27/50\n",
      "400/400 [==============================] - 0s 873us/step - loss: 5.3311e-05 - acc: 1.0000 - val_loss: 0.2351 - val_acc: 0.9500\n",
      "Epoch 28/50\n",
      "400/400 [==============================] - 0s 950us/step - loss: 7.4385e-04 - acc: 1.0000 - val_loss: 0.2547 - val_acc: 0.9700\n",
      "Epoch 29/50\n",
      "400/400 [==============================] - 0s 898us/step - loss: 5.4692e-05 - acc: 1.0000 - val_loss: 0.2426 - val_acc: 0.9700\n",
      "Epoch 30/50\n",
      "400/400 [==============================] - 0s 868us/step - loss: 0.0016 - acc: 1.0000 - val_loss: 0.3069 - val_acc: 0.9600\n",
      "Epoch 31/50\n",
      "400/400 [==============================] - 0s 865us/step - loss: 0.0012 - acc: 1.0000 - val_loss: 0.2546 - val_acc: 0.9500\n",
      "Epoch 32/50\n",
      "400/400 [==============================] - 0s 870us/step - loss: 0.0022 - acc: 1.0000 - val_loss: 0.2563 - val_acc: 0.9500\n",
      "Epoch 33/50\n",
      "400/400 [==============================] - 0s 858us/step - loss: 0.0964 - acc: 0.9725 - val_loss: 0.2621 - val_acc: 0.9700\n",
      "Epoch 34/50\n",
      "400/400 [==============================] - 0s 965us/step - loss: 1.4947e-04 - acc: 1.0000 - val_loss: 0.2610 - val_acc: 0.9700\n",
      "Epoch 35/50\n",
      "400/400 [==============================] - 0s 868us/step - loss: 0.0016 - acc: 1.0000 - val_loss: 0.2719 - val_acc: 0.9500\n",
      "Epoch 36/50\n",
      "400/400 [==============================] - 0s 855us/step - loss: 2.3221e-05 - acc: 1.0000 - val_loss: 0.2716 - val_acc: 0.9500\n",
      "Epoch 37/50\n",
      "400/400 [==============================] - 0s 858us/step - loss: 0.0089 - acc: 0.9975 - val_loss: 0.2859 - val_acc: 0.9700\n",
      "Epoch 38/50\n",
      "400/400 [==============================] - 0s 875us/step - loss: 2.4090e-04 - acc: 1.0000 - val_loss: 0.2715 - val_acc: 0.9500\n",
      "Epoch 39/50\n",
      "400/400 [==============================] - 0s 865us/step - loss: 1.1602e-04 - acc: 1.0000 - val_loss: 0.2783 - val_acc: 0.9500\n",
      "Epoch 40/50\n",
      "400/400 [==============================] - 0s 863us/step - loss: 2.5742e-05 - acc: 1.0000 - val_loss: 0.2841 - val_acc: 0.9500\n",
      "Epoch 41/50\n",
      "400/400 [==============================] - 0s 868us/step - loss: 1.1411e-05 - acc: 1.0000 - val_loss: 0.2801 - val_acc: 0.9500\n",
      "Epoch 42/50\n",
      "400/400 [==============================] - 0s 963us/step - loss: 7.1294e-05 - acc: 1.0000 - val_loss: 0.2621 - val_acc: 0.9700\n",
      "Epoch 43/50\n",
      "400/400 [==============================] - 0s 853us/step - loss: 1.5010e-05 - acc: 1.0000 - val_loss: 0.2753 - val_acc: 0.9700\n",
      "Epoch 44/50\n",
      "400/400 [==============================] - 0s 860us/step - loss: 3.9362e-06 - acc: 1.0000 - val_loss: 0.2720 - val_acc: 0.9600\n",
      "Epoch 45/50\n",
      "400/400 [==============================] - 0s 865us/step - loss: 3.6688e-05 - acc: 1.0000 - val_loss: 0.3077 - val_acc: 0.9600\n",
      "Epoch 46/50\n",
      "400/400 [==============================] - 0s 855us/step - loss: 7.1249e-06 - acc: 1.0000 - val_loss: 0.3070 - val_acc: 0.9600\n",
      "Epoch 47/50\n",
      "400/400 [==============================] - 0s 950us/step - loss: 2.7769e-06 - acc: 1.0000 - val_loss: 0.3105 - val_acc: 0.9700\n",
      "Epoch 48/50\n",
      "400/400 [==============================] - 0s 860us/step - loss: 5.4962e-06 - acc: 1.0000 - val_loss: 0.3184 - val_acc: 0.9500\n",
      "Epoch 49/50\n",
      "400/400 [==============================] - 0s 853us/step - loss: 0.0438 - acc: 0.9850 - val_loss: 0.2470 - val_acc: 0.9600\n",
      "Epoch 50/50\n",
      "400/400 [==============================] - 0s 855us/step - loss: 5.5508e-04 - acc: 1.0000 - val_loss: 0.2798 - val_acc: 0.9700\n"
     ]
    }
   ],
   "source": [
    "from keras.utils import to_categorical\n",
    "# 只需要训练分类器模型即可，不需要训练特征提取器\n",
    "train_data = np.load(os.path.join(save_folder,'bottleneck_features_train.npy')) # 加载训练图片集的所有图片的VGG16-notop特征\n",
    "train_labels = np.array([0] * 80 + [1] * 80+ [2]*80+[3]*80+[4]*80)\n",
    "# label是每个类别80张图片，共5个类别\n",
    "# 设置标签，并规范成Keras默认格式\n",
    "train_labels = to_categorical(train_labels, class_num)\n",
    "\n",
    "validation_data = np.load(os.path.join(save_folder,'bottleneck_features_val.npy'))\n",
    "validation_labels = np.array([0] * 20 + [1] * 20+ [2]*20+[3]*20+[4]*20)\n",
    "validation_labels = to_categorical(validation_labels, class_num)\n",
    "\n",
    "# 构建分类器模型\n",
    "clf_model=my_model()\n",
    "history_ft = clf_model.fit(train_data, train_labels,\n",
    "              epochs=epochs,\n",
    "              batch_size=batch_size,\n",
    "              validation_data=(validation_data, validation_labels))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 画图，将训练时的acc和loss都绘制到图上\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "def plot_training(history):\n",
    "    plt.figure(12)\n",
    "    \n",
    "    plt.subplot(121)\n",
    "    train_acc = history.history['acc']\n",
    "    val_acc = history.history['val_acc']\n",
    "    epochs = range(len(train_acc))\n",
    "    plt.plot(epochs, train_acc, 'b',label='train_acc')\n",
    "    plt.plot(epochs, val_acc, 'r',label='test_acc')\n",
    "    plt.title('Train and Test accuracy')\n",
    "    plt.legend()\n",
    "    \n",
    "    plt.subplot(122)\n",
    "    train_loss = history.history['loss']\n",
    "    val_loss = history.history['val_loss']\n",
    "    epochs = range(len(train_loss))\n",
    "    plt.plot(epochs, train_loss, 'b',label='train_loss')\n",
    "    plt.plot(epochs, val_loss, 'r',label='test_loss')\n",
    "    plt.title('Train and Test loss')\n",
    "    plt.legend()\n",
    " \n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_training(history_ft)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "clf_model.save_weights(os.path.join(save_folder,'top_FC_model'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
